using UnityEngine;
using Plane=Math.Plane;

namespace Cameras
{
    public static class Frustum
    {
        public static Matrix4x4 GetViewProjMatrix(Camera camera)
        {
            Matrix4x4 proj = camera.projectionMatrix;
            Matrix4x4 view = camera.worldToCameraMatrix;

            proj = proj.transpose;
            view.m32 *= -1.0f;
            view = view.transpose;

            return view*proj;
        }

        public static Plane[] GetPlanes(Matrix4x4 projMat)
		{
            Plane[] frustum = new Plane[6];

            /*
                column-major matrix form:
                
                0   4   8  12
                1   5   9  13
                2   6  10  14
                3   7  11  15
                
                struct Matrix4x4
                {
                    float _11, _21, _31, _41;
                    float _12, _22, _32, _42;
                    float _13, _23, _33, _43;
                    float _14, _24, _34, _44;
                };
            */

            //left
            frustum[0] = new Plane(
            projMat[12] + projMat[ 0],
            projMat[13] + projMat[ 1],
            projMat[14] + projMat[ 2],
            projMat[15] + projMat[ 3]);

            //right
            frustum[1] = new Plane(
            projMat[12] - projMat[ 0],
            projMat[13] - projMat[ 1],
            projMat[14] - projMat[ 2],
            projMat[15] - projMat[ 3]);
			
            //top
            frustum[2] = new Plane(
            projMat[12] - projMat[ 4],
            projMat[13] - projMat[ 5],
            projMat[14] - projMat[ 6],
            projMat[15] - projMat[ 7]);

            //bottom
            frustum[3] = new Plane(
            projMat[12] + projMat[ 4],
            projMat[13] + projMat[ 5],
            projMat[14] + projMat[ 6],
            projMat[15] + projMat[ 7]);
			
            //near
            frustum[4] = new Plane(
            projMat[12] + projMat[ 8],
            projMat[13] + projMat[ 9],
            projMat[14] + projMat[10],
            projMat[15] + projMat[11]);

            //far
            frustum[5] = new Plane(
            projMat[12] - projMat[ 8],
            projMat[13] - projMat[ 9],
            projMat[14] - projMat[10],
            projMat[15] - projMat[11]);
            
            return frustum;
        }
    }
}